package game.view;

import game.*;

import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.*;

import javax.swing.*;

/**
 * Game UI - user interface of this game.
 * @author Natchanon Hongladaromp
 *
 */
public class GameUI extends JFrame implements Observer
{
	private Game game;
	private JLabel round;
	private JLabel time;
	private Board board;
	private ScoreBoard scoreBoard;
	private SelectModeUI selectMode;
	private ScoreBoardUI scoreUI;
	private JButton start;

	/**
	 * Construct for this ui.
	 * @param game
	 */
	public GameUI(Game game)
	{
		this.game = game;
		setTitle("24 Game");
		
		round = new JLabel("");
		time = new JLabel("");
		board = new Board(game);
		scoreBoard = new ScoreBoard(game.getMode());
		scoreUI = new ScoreBoardUI(scoreBoard);
		scoreBoard.addObserver(scoreUI);
		initComponents();

	}

	/**
	 * Runs method.
	 */
	public void run()
	{
		setPreferredSize(new Dimension(1200,500));
		pack();
		setVisible(true);
	}

	/**
	 * initial components.
	 */
	private void initComponents()
	{
		JPanel pane = new JPanel();
		pane.setLayout(new GridBagLayout());
		GridBagConstraints c = new GridBagConstraints();

		JButton button;
				
		selectMode = new SelectModeUI(game);
		c.fill = GridBagConstraints.HORIZONTAL;
		c.gridx = 0;
		c.gridy = 0;
		c.gridheight = 2;
		pane.add(selectMode, c);
		
		start = new JButton("Start");
		start.addActionListener(new ActionListener()
		{

			@Override
			public void actionPerformed(ActionEvent e)
			{
				game.start();
				selectMode.off();
				start.setEnabled(false);
			}
		});
		c.gridx = 0;
		c.gridy = 2;
		c.gridheight = 1;
		pane.add(start, c);
		
		NumbersUI numUI = new NumbersUI(game, board);
		game.addObserver(numUI);
		
		c.ipadx = 120;
		c.ipady = 20;
		c.gridx = 1;
		c.gridy = 0;
		pane.add(numUI,c);
		
		BoardUI boardUI = new BoardUI(board);
		board.addObserver(boardUI);
		c.gridx = 1;
		c.gridy = 1;
		pane.add(boardUI,c);
		
		OperationsUI operUI = new OperationsUI(game, board);
		c.gridx = 1;
		c.gridy = 2;
		pane.add(operUI,c);

		round = new JLabel(String.format("Round %d",game.getRound()));
		round.setHorizontalAlignment( SwingConstants.CENTER );
		c.ipadx = 40;
		c.gridx = 2;
		c.gridy = 0;
		pane.add(round, c);


		time = new JLabel(String.format("TIME: %2.0f",game.getTime()));
		time.setHorizontalAlignment( SwingConstants.CENTER );
		c.ipadx = 40;
		c.gridx = 3;
		c.gridy = 0;
		pane.add(time, c);
		
		button = new JButton("Reset");
		button.addActionListener(new ActionListener()
		{

			@Override
			public void actionPerformed(ActionEvent e)
			{
				game.reset();
				board.reset();
			}
		});
		c.gridx = 2;
		c.gridy = 1;
		pane.add(button, c);

		button = new JButton("Pass");
		button.addActionListener(new ActionListener()
		{

			@Override
			public void actionPerformed(ActionEvent arg0)
			{
				game.pass();
				board.reset();
			}
		});
		c.gridx = 3;
		c.gridy = 1;
		pane.add(button, c);

		button = new JButton("Hint");
		button.addActionListener(new ActionListener()
		{

			@Override
			public void actionPerformed(ActionEvent arg0)
			{
				JOptionPane.showMessageDialog(new JFrame(),
						game.getHint(),
						"Hint!",
						JOptionPane.PLAIN_MESSAGE);
			}
		});
		c.gridx = 2;
		c.gridy = 2;
		pane.add(button, c);
		
		button = new JButton("Score");
		button.addActionListener(new ActionListener()
		{

			@Override
			public void actionPerformed(ActionEvent arg0)
			{
				scoreUI.run();
			}
		});
		c.gridx = 3;
		c.gridy = 2;
		pane.add(button, c);
		
		add(pane);
		setDefaultCloseOperation(EXIT_ON_CLOSE);
	}

	@Override
	public void update(Observable arg0, Object arg1)
	{
		if(arg1 == UpdateType.UPDATE_TIME)
		{
			time.setText(String.format("TIME: %.2f",game.getTime()));
		}
		
		else if(arg1 == UpdateType.UPDATE_END)
		{
			String s = String.format("Your score is %.2f\nEnter your name",game.getScore());
			
			String name = JOptionPane.showInputDialog(null, s);
			
			scoreBoard.addScore(name, game.getScore());
			
			start.setEnabled(true);
			selectMode.on();
		}
		

		else if(arg1 == UpdateType.UPDATE_NUMBER)
		{

			String sRound = String.format("Round %d",game.getRound());
			round.setText(sRound);
		}
	}
}
